﻿using System.Windows;
using System.Windows.Input;

namespace WPFTemplateLib.Attached
{
	/// <summary>
	/// 用于设置控件元素焦点的附加属性帮助类（来源于网络并修改）
	/// </summary>
	public class FocusAttached
	{
		#region [附加属性]是否获取焦点
		public static bool GetIsFocused(DependencyObject obj)
		{
			return (bool)obj.GetValue(IsFocusedProperty);
		}
		public static void SetIsFocused(DependencyObject obj, bool value)
		{
			obj.SetValue(IsFocusedProperty, value);
		}
		/// <summary>
		/// [附加属性]是否获取焦点
		/// </summary>
		public static readonly DependencyProperty IsFocusedProperty =
			DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusAttached), new FrameworkPropertyMetadata(IsFocusedChanged) { BindsTwoWayByDefault = true });
		#endregion

		/// <summary>
		/// IsFocused 附加属性改变时触发
		/// </summary>
		private static void IsFocusedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
		{
			var fe = (FrameworkElement)obj;

			if(e.OldValue == null)
			{
				fe.GotFocus += FrameworkElement_GotFocus;
				fe.LostFocus += FrameworkElement_LostFocus;
			}

			if(!fe.IsVisible)
			{
				fe.IsVisibleChanged += FrameworkElement_IsVisibleChanged;
			}

			if((bool)e.NewValue)
			{
				fe.Focus();
				Keyboard.Focus(fe);
			}
		}

		/// <summary>
		/// 元素获取焦点时触发
		/// </summary>
		private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
		{
			((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
		}

		/// <summary>
		/// 元素失去焦点时触发
		/// </summary>
		private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
		{
			((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
		}

		/// <summary>
		/// 元素可见性改变时触发
		/// </summary>
		private static void FrameworkElement_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
		{
			var fe = (FrameworkElement)sender;
			if(fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
			{
				fe.IsVisibleChanged -= FrameworkElement_IsVisibleChanged;
				fe.Focus();
			}
		}
	}
}
